/**
 * @author Alias Cummins
 */
 
import flash.display.BitmapData;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.filters.DisplacementMapFilter;
import flash.geom.Matrix;
import flash.geom.Point;
 
class com.proalias.perlineffects.Vapour extends MovieClip{
	        private var $vapourBmp:BitmapData;
			private var $offsets:Array;
			private var $tempBmp:BitmapData;
			private var $prevBmp:BitmapData;
			private var $greyBmp:BitmapData;
			private var $mtx:Matrix;
			private var $shrinkTmp:Matrix;
			
			private var $k:Number;
			private var $c:Number;
						
			private var $pnt:Point;
			private var $blurF:BlurFilter;
			private var $greyscaleCMF:ColorMatrixFilter;
			private var $vapourCMF:ColorMatrixFilter;
			private var $dispMapF:DisplacementMapFilter;
			private var $blurDifference:BlurFilter;
			
			
			
			public var canvas:MovieClip;
			public var vapourHolder:MovieClip;

		private var $enabled : Boolean;
			
        public function Vapour (){
			trace("Vapour.Vapour()");    
			init();
	    	enabled = true;
	    }
	    
	    private function init():Void{
	    	trace("Vapour.init()");
	     	$c = 1;
	     	
        	
            $vapourBmp = new flash.display.BitmapData(160, 120, false, 0);//empty bitmap for fire
            $prevBmp = new flash.display.BitmapData(160, 120, false, 0);//empty bitmap for difference between 2 frame
            $tempBmp = new flash.display.BitmapData(160, 120, false, 0);//bitmap for compositing
            $greyBmp = new flash.display.BitmapData(160, 120, false, 0x00FF7700);
            $mtx = new flash.geom.Matrix();// regular identity matrix for feeding to transforms
            $pnt = new flash.geom.Point(0,0);// regular point for feeding to transforms
            $blurF = new flash.filters.BlurFilter(12, 12, 1);
            $k = 0;//incremental counter for tracking phase in perlin noise functions 
            
            
            /*
             * This is a color matrix filter which tints the vapour whatever colour you want it
             */
            $vapourCMF = new flash.filters.ColorMatrixFilter(	[0.5,		0.1,	0, 		0,		0,	 	
																 0,			1, 		0,   	0,		0,
																 0,			0, 		1, 		0,  	0,
																 0,			0, 		1, 		0,		0]);
																 
			$blurDifference = new flash.filters.BlurFilter(12,12,1);//blur filter for softening the sequential changes												 
			
			
            $dispMapF = new flash.filters.DisplacementMapFilter($tempBmp, $pnt, 1, 2, -5, -10, "clamp");
			$offsets = [new Point(1, 1.3),new Point(1.5, 1.9),new Point(1.7,5),new Point(1.7,5)];
			
			
	    	configUI();
	    	useHandCursor = false;
	    	canvas._visible = false;
	    	//_width = Stage.width;
        	//_height = Stage.height;
	    }
        
        function onPress() : Void {
        	canvas.mouseMover.play();
        	$c += 20;
        	//clear();
        	//init();
        }
        
        public function setColorMatrixFilter(cmf:ColorMatrixFilter) : Void {
        	trace("Vapour.setColorMatrixFilter("+cmf+")");
        	$vapourCMF = cmf;
        }
        	
        public function get enabled():Boolean{
        	return $enabled;
        }
        
        public function set enabled(val:Boolean){
        	$enabled = val;
        	if (val == true && onEnterFrame == null){
        		onEnterFrame = update;
        	}else if (val == false){
        		onEnterFrame = null;
        	}
        }
        
        
        /*
         * free up the memory heap and start again
         */
        public function clear() : Void {
        	$vapourBmp.dispose();
        	$prevBmp.dispose();
        	$tempBmp.dispose();
        	$greyBmp.dispose();
        	init();
        }
        
        
        function configUI() : Void {
        	trace("Vapour.configUI()");
            vapourHolder.attachBitmap($vapourBmp, 1);
            vapourHolder.blendMode = "add";
            
            //_root.debug1.attachBitmap($prevBmp,1);
           // _root.debug2.attachBitmap($tempBmp,1);
            //_root.debug3.attachBitmap($vapourBmp,1);
        }
        
        function update() : Void {
        	trace("Vapour.onEnterFrame()");
        	canvas.mouseMover._x = canvas._xmouse;
        	canvas.mouseMover._y = canvas._ymouse;
        	

        	var r:Number = 2; //red value
        	var g:Number = 2; //blue value
        	var b:Number = 2; //green value
        	
        	
        	//copy the pixels from the previous frame
            $tempBmp.copyPixels($prevBmp, $prevBmp.rectangle, $pnt);
            //get the current frame
            $prevBmp.draw(canvas);
            //blur the last frame
            $prevBmp.applyFilter($prevBmp,$prevBmp.rectangle,$pnt,$blurDifference);
            
            $tempBmp.draw($prevBmp, $mtx, null, "difference");
            $tempBmp.applyFilter($tempBmp, $tempBmp.rectangle, $pnt, $blurF);
            $vapourBmp.draw($tempBmp, $mtx, null, "add");
			$k += 0.01;
			
			//update the perlin noise offests 
			for (var i:Number=0;i<$offsets.length;i++){
				$offsets[i].x += Math.sin($k)+i*1;
				$offsets[i].y += (i*1)+1;
				//trace("Vapour.onEnterFrame::$offsets["+i+"].x="+$offsets[i].x);
				//trace("Vapour.onEnterFrame::$offsets["+i+"].y="+$offsets[i].y);
			}
			
			//draw the perlin noise
            $tempBmp.perlinNoise(32, 64+(Math.sin($k)*2), 3, Math.random(), false, true, 8, true,$offsets);
          	$tempBmp.draw($greyBmp, $mtx, null, "darken");
          	//apply the displacement map filter
            $vapourBmp.applyFilter($vapourBmp, $vapourBmp.rectangle, $pnt, $dispMapF);
            //tint the greyscale image to the desired colour
          	$vapourBmp.applyFilter($vapourBmp, $vapourBmp.rectangle, $pnt, $vapourCMF);
        }
}